package com.h819.core.web.jqgrid;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.RequestAware;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 该Struts2向客户端返回一个json对象。为了简便，数据不是从数据库获得的。
 * 
 * jqGrid默认期望返回的json对象格式要求如下： {"page":"1","total":"2","records":"13", "rows":[
 * {id
 * :"1",cell:["1","polaris","男","polaris@gmail.com","772618379","18329382732",
 * "1985-10-2"]},
 * {id:"2",cell:["2","张三","女","zhangsan@163.com","272618382","15329382732"
 * ,"1986-10-12"]},
 * {id:"3",cell:["3","王五","女","wangwu@yahoo.com","172635372","13329389832"
 * ,"1987-12-21"]},
 * {id:"4",cell:["4","赵六","男","zhaoliu@sina.com","372618332","18929343731"
 * ,"1988-09-22"]} ] } 当然，在js中，可以通过jqGrid的jsonReader属性来修改默认格式
 * 因为默认的格式，rows的数据要求顺序不能变，且每个字段都得有值（空也得有"")。因而， 在jsonReader中定义repeatitems :
 * false。这样，rows就变成了： "rows":[
 * {id:"1",userName:"polaris",gender:"男",email:"polaris@gmail.com"
 * ,QQ:"772618379",mobilePhone:"18329382732",birthday:"1985-10-2"]},
 * {id:"2",userName
 * :"徐新华",gender:"男",email:"xh.xu@163.com",QQ:"272618382",mobilePhone
 * :"15329382732",birthday:"1986-10-12"]},
 * {id:"3",userName:"王五",gender:"女",email
 * :"wangwu@yahoo.com",QQ:"172635372",mobilePhone
 * :"13329389832",birthday:"1987-12-21"]},
 * {id:"4",userName:"赵六",gender:"女",email
 * :"zhaoliu@sina.com",QQ:"372618332",mobilePhone
 * :"18929343731",birthday:"1988-09-22"]} ]
 * 
 * 这是 jqgird 的 JSON dot notation 格式
 * 
 * @author xuxinhua
 * 
 */

// 在被继承的类中，已经包含了 jqgird 传递过来的参数，并且会被 struts2 请求参数赋值
public class JqgridListAction extends JqgridListBaseAction implements
		RequestAware {
	private static final long serialVersionUID = 132383828833L;
	Logger log = Logger.getLogger(JqgridListAction.class);

	int size = 28;
	int searchSize = 1;

	@SuppressWarnings("unchecked")
	Map request;

	/**
	 * 该方法得到数据并构造json对象以便返回给客户端
	 * 
	 * @return
	 * @throws Exception
	 */
	public String execute() throws Exception {

		// 执行 search 操作

		log.info("isSearch() : " + isSearch());
		if (this.isSearch()) {
			search();

		} else {

			// 准备数据
			prepareListDate();
		}

		// 第一次查询时，显示为第一页。此时 传过来的参数 page 值为 0
		// 测试是否已经根据 prmNames 参数设置自动赋值

		// page 类根据每页记录数量和总记录数计算出

		log.info("isSearch :" + this.isSearch());
		log.info("Search :" + this.getSearch());
		log.info("SearchField :" + this.getSearchField());
		log.info("SearchString :" + this.getSearchString());
		log.info("SearchOper :" + this.getSearchOper());

		// 给 Page 函数设定必要参数
		// jqgrid 的一些参数，已经通过配置，传入到 this.getPage()方法中
		Page p = this.getPage();
		// 如果利用分页类进行操作，那么分页类必须获得以下几个值。
		p.setTotalCount(27);
		// 下面几个值已经利用 jqgrid ，在 JqgridListBaseAction 类中 setPage 方法中 赋值完成
		// p.setPageNo(pageNo);
		// p.setPageSize(pageSize)
		// p.setOrderBy(orderBy)

		// 给 jqgrid 设置必要参数，传递到前台
		this.setCurPageNo(p.getPageNo());
		this.setTotalRecords(p.getTotalCount());
		this.setTotalPages(p.getTotalPages());
		// 下面模拟代码中完成
		// this.setDataRows(rows);

		// 下面模拟分页，
		List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();		
		int begin = p.getFirst();
		int end = begin + p.getPageSize()-1;//可以在 page 类中增加一个方法，用来得到每页的末尾序号

		if (end >= this.getTotalRecords())
			end = Long.valueOf(this.getTotalRecords()).intValue();

		log.info("begin: " + begin);
		log.info("end: " + end);
		for (int i = begin-1; i < end; i++) {
			log.info("i: " + i + 1);
			rows.add(this.getDataRows().get(i));
		}

		this.setDataRows(rows);

		/**
		 * 总结: 利用本方法，必须赋值的有 5 个 方法
		 */

		// p.setTotalCount(27);
		// this.setCurPageNo(p.getPageNo());
		// this.setTotalRecords(p.getTotalCount());
		// this.setTotalPages(p.getTotalPages());
		// this.setDataRows(rows);

		//

		// 下述为测试内容：
		log.info("当前页号：" + this.getCurPageNo());
		log.info("每页显示数据数量：" + p.getPageSize());
		log.info("数据总量：" + rows.size());
		log.info("排序变量：" + p.getOrderBy());
		log.info("升序/降序：" + p.getOrder());

		// for (Map m : this.getDataRows()) {
		// StringUtils.center("当前页面的数据 ", 80, '*');
		// for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
		// Map.Entry entry = (Map.Entry) it.next();
		// out.println(entry.getKey() + " = " + entry.getValue());
		//
		// }
		//
		// out.println(" ========= ");
		// }

		return SUCCESS;
	}

	/**
	 * 如果进行的是 search 操作，则执行此方法. 通过 this.isSearch() 方法判断是否是 search 操作
	 */
	public void search() {

		// 过程同 prepareListDate ，只是添加了一些搜索条件
		// 单条件搜索和多条件搜索，只是参数不同而已。

		// 提交过来的参数，通过 struts 可以自动获得。因为参数每个项目都不同，所以需要根据实际情况来编写
	}

	/**
	 * 如果执行的是浏览操作，执行此方法。
	 */
	private void prepareListDate() {

		// 构建几条测试数据

		for (int i = 1; i < 28; ++i) {
			// 定义一个Map<String,Object>存放一行行数据。（跟从Servlet获得数据类似，只不过此处不需要用json-lib）
			Map<String, Object> row = new HashMap<String, Object>();

			row.put("id", i);
			if (i % 2 == 0) {
				row.put("userName", "polaris");
				row.put("gender", "女");
			} else {
				row.put("userName", "test");
				row.put("gender", "男");
			}

			// 制作单条
			row.put("email", "polaris@gmail.com");
			row.put("QQ", "772" + i + "1837" + i);
			row.put("mobilePhone", "132" + i + "1837" + i + "3" + i);
			row.put("birthday", "198" + i + "-10-" + "1" + i);
			row.put("action", "执行动作");
			row.put("selectdemo", "语种");
			// 放入结果集
			this.getDataRows().add(row);
		}

	}

	/*
	 * 以下getter方法必须实现，struts2-json插件会将这些getter方法序列化，以便输出json对象。
	 * 这些getter方法只需返回相应的属性即可。如getCurPage应该返回curPage （curPage在JsonBaseAction中有定义）
	 */
	@Override
	public int getCurPageNo() {
		return this.curPageNo;
	}

	@Override
	public List<Map<String, Object>> getDataRows() {
		return this.dataRows;
	}

	@Override
	public long getTotalPages() {
		return this.totalPages;
	}

	@Override
	public long getTotalRecords() {
		return this.totalRecords;
	}

	public void setRequest(Map<String, Object> request) {
		// TODO Auto-generated method stub
		this.request = request;

	}
}